package com.administrator.scoreManageSys.service.impl;

import com.administrator.scoreManageSys.entity.system.User;
import com.administrator.scoreManageSys.mapper.system.SystemUserAuthenticationMapper;
import com.administrator.scoreManageSys.service.SystemUserAuthenticationService;
import com.administrator.scoreManageSys.system.ReturnMsg;
import com.administrator.scoreManageSys.utils.JwtTokenUtils;
import com.administrator.scoreManageSys.utils.Md5Utils;
import com.administrator.scoreManageSys.utils.RedisUtils;
import com.administrator.scoreManageSys.utils.ResultUtils;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

import static com.administrator.scoreManageSys.system.ReturnMsg.NO_REGISTER;
import static com.administrator.scoreManageSys.system.SystemConstant.MD5_KEY;
import static com.administrator.scoreManageSys.system.SystemConstant.SYSTEM_USER_MENU;

/**
 * @author Administrator
 */
@Service
public class SystemUserAuthenticationServiceImpl implements SystemUserAuthenticationService {

    @Resource
    private ResultUtils resultUtils;
    @Resource
    private Md5Utils md5Utils;
    @Resource
    private RedisUtils redisUtils;
    @Resource
    private SystemUserAuthenticationMapper systemUserAuthenticationMapper;

    /**
     * 登录
     *
     * @param account  用户名
     * @param password 用户密码
     * @return 执行结果
     */
    @Override
    public JSONObject login(String account, String password) {
        //登录到期时间 （单位毫秒） 120分钟token有效期
        Long expire = 1000 * 60 * 120L;
        //根据手机号码查询系统管理员
        User user = systemUserAuthenticationMapper.selectUserByUserName(account);
        if (user == null) {
            return resultUtils.resultJson(null, NO_REGISTER);
        }
        //获取用户id
        Long userId = user.getId();
        //对密码进行二次加密
        password = md5Utils.encrypt(password + MD5_KEY);
        //2 判断用户密码是否正确
        if (password.equals(user.getPassword())) {
            //创建返回用户token的json
            JSONObject data = new JSONObject();
            //创建用户token
            String token = "";
            //登录成功! 检查用户是否存在
            if (redisUtils.userDoesItExist(userId)) {
                //用户存在则更新登录到期时间
                redisUtils.updateKeyTime(userId, expire);
                //获取token返回给前端
                token = redisUtils.getToken(userId);
            } else {
                //用户不存在则 生成Token
                token = JwtTokenUtils.generateAuthenticationToken(userId, user.getRole(), expire);
                //將token存入redis
                redisUtils.loginInformationToken(userId, token, expire);
            }
            data.put("token", "Bearer " + token);
            return resultUtils.resultSuccessData(data);
        }
        return resultUtils.resultCustomMsg(ReturnMsg.FAILED, "密码错误!");
    }

    /**
     * 登出
     *
     * @param userId 登出用户id
     * @return 执行结果
     */
    @Override
    public JSONObject systemUserSignOut(Long userId) {
        //用户登出 清除redis中的相关登录token
        redisUtils.deleteAssignValue(userId);
        return resultUtils.resultSuccess();
    }

    /**
     * 获取菜单
     *
     * @param role 用户角色
     * @return 菜单列表
     */
    @Override
    public JSONObject getUserMenu(Long role) {
        //获取角色对应的菜单
        JSONObject roles = redisUtils.getMenu(role);
        JSONArray menus = roles.getJSONArray(SYSTEM_USER_MENU);
        JSONArray result = new JSONArray();
        for (Object menu : menus) {
            JSONArray jsonArray = new JSONArray();
            JSONObject jsonObject = JSONObject.parseObject(String.valueOf(menu));
            JSONArray children = jsonObject.getJSONArray("child");
            for (Object child : children) {
                JSONObject secondaryChild = JSONObject.parseObject(String.valueOf(child));
                JSONArray child1 = secondaryChild.getJSONArray("child");
                for (Object o : child1) {
                    JSONObject child2 = JSONObject.parseObject(String.valueOf(o));
                    jsonArray.add(child2);
                }
            }
            jsonObject.put("child", jsonArray);
            result.add(jsonObject);
        }
        return resultUtils.resultSuccessData(result);
    }

    /**
     * 获取用户个人信息
     *
     * @param userId 用户id
     * @return 个人信息User
     */
    @Override
    public JSONObject getUser(Long userId) {
        User user = systemUserAuthenticationMapper.getUserByUserId(userId);
        int checkSecurity = systemUserAuthenticationMapper.checkSecurity(user);
        user.setIsSecuritySettings((long) checkSecurity);
        return resultUtils.resultSuccessData(user);
    }

    /**
     * 用户设置密保
     *
     * @param passwordProtection 设置密保集合
     * @param userId
     * @return 操作结果
     */
    @Override
    public JSONObject setPasswordProtection(JSONArray passwordProtection, Long userId) {
        systemUserAuthenticationMapper.deleteProtection(userId);
        systemUserAuthenticationMapper.setPasswordProtection(passwordProtection, userId);
        return resultUtils.resultSuccess();
    }

    /**
     * 用户更新密保
     *
     * @param passwordProtection 设置密保集合
     * @param userId             用户id
     * @return 操作结果
     */
    @Override
    public JSONObject renewPasswordProtection(JSONArray passwordProtection, Long userId) {
        systemUserAuthenticationMapper.deleteProtection(userId);
        systemUserAuthenticationMapper.setPasswordProtection(passwordProtection, userId);
        return resultUtils.resultSuccess();
    }

    /**
     * 修改密码
     *
     * @param userId      用户id
     * @param oldPassword 旧密码
     * @param newPassword 新密码
     * @return 修改结果
     */
    @Override
    public JSONObject changePassword(Long userId, String oldPassword, String newPassword) {
        //根据手机号码查询系统管理员
        User user = systemUserAuthenticationMapper.getUserByUserId(userId);
        //对旧密码进行二次加密
        oldPassword = md5Utils.encrypt(oldPassword + MD5_KEY);
        //2 判断用户密码是否正确
        if (oldPassword.equals(user.getPassword())) {
            //对新密码进行二次加密
            newPassword = md5Utils.encrypt(newPassword + MD5_KEY);
            systemUserAuthenticationMapper.changePassword(userId, newPassword);
            return resultUtils.resultSuccess();
        }
        return resultUtils.resultCustomMsg(ReturnMsg.FAILED, "密码错误!");
    }

    /**
     * 忘记密码
     *
     * @param account          账号
     * @param securityAnswer   密保问题
     * @param securityQuestion 密保答案
     * @param newPassword      新密码
     * @return 操作结果
     */
    @Override
    public JSONObject forgotPassword(String account, Long securityAnswer, String securityQuestion, String newPassword) {
        //根据账号查询用户密保
        JSONObject user = systemUserAuthenticationMapper.selectUserPasswordProtection(account);
        if (user==null){
            return resultUtils.resultCustomMsg(ReturnMsg.FAILED, "无效账号");
        }
        Long securityAnswer1 = user.getLong("securityAnswer");
        Long userId = user.getLong("userId");
        String securityQuestion1 = user.getString("securityQuestion");
        if (securityAnswer1 == null || securityQuestion1 == null) {
            return resultUtils.resultCustomMsg(ReturnMsg.FAILED, "账号无有效密保 请联系老师或者管理员!");
        }
        if ((long) securityAnswer1 == securityAnswer && securityQuestion1.equals(securityQuestion)) {
            //对新密码进行二次加密
            newPassword = md5Utils.encrypt(newPassword + MD5_KEY);
            systemUserAuthenticationMapper.changePassword(userId, newPassword);
            return resultUtils.resultSuccess();
        }
        return resultUtils.resultCustomMsg(ReturnMsg.FAILED, "密保错误!");
    }
}
